//
//  TCToast.swift
//  TCToast
//
//  Created by 叮叮 on 2021/3/17.
//

import Foundation
import UIKit

enum ToastType {
    /// 加载类型
    case loading
    /// 弹窗结果类型
    case result
}

enum ToastDisplayType {
    /// 暗黑模式
    case dark
    /// 明亮模式
    case light
}

class TCToast: UIView {
    
    /// 出现动画时间
    static var showTime = 0.25
    /// 消失动画时间
    static var dismissTime = 0.25
    /// 指示器动画时间
    static var indicatorTime = 0.25
    /// 弹窗模式
    static var toastDisplayType = ToastDisplayType.light
    /// 遮罩是否可穿透
    static var isUserInteractionEnabled = true
    /// 遮罩颜色
    static var maskColor = UIColor.black.withAlphaComponent(0.1)
    /// Toast内容
    var contentView: UIView?
    /// 视图缩放比例
    let scaleRatio: CGFloat = 0.8
    /// 遮罩类型
    var toastType: ToastType?
    /// 背景遮罩
    private(set) var  backgroundView: UIView?
    
    /// 显示加载视图
    static func show(in view: UIView, loadingText text: String = "加载中...", dismissCompletion completion: (() -> Void)? = nil) {
        
        var toast = getToast(in: view)
        
        if toast == nil {
            toast = TCToast.init(frame: UIScreen.main.bounds, toastType: .loading)
            view.addSubview(toast!)
            toast?.animateShow()
        }
        
        if let certainToast = toast {
            certainToast.setText(text: text)
        }
    }
    
    /// 加载视图消失
    static func dismiss(in view: UIView, completion: (() -> Void)? = nil) {
        if let certainToast = getToast(in: view) {
            certainToast.animateHide(completion: completion)
        }
    }
    
    /// 显示结果 Toast
    static func show(in view: UIView, text: String? = nil, delay: Double? = 1.5, type: ResultType = .none, dismissCompletion completion: (() -> Void)? = nil) {
        var toast = getToast(in: view)
        if toast == nil {
            toast = TCToast.init(frame: UIScreen.main.bounds, toastType: .result, resultType: type)
            view.addSubview(toast!)
            toast?.animateShow()
        }
        
        if toast?.toastType == .loading {
            toast?.removeFromSuperview()
            toast = TCToast.init(frame: UIScreen.main.bounds, toastType: .result, resultType: type)
            view.addSubview(toast!)
            if let result = toast {
                if let toastContentView = result.contentView as? ToastResultView {
                    toastContentView.startAnimation()
                }
            }
        }
        
        guard let certainToast = toast else { return }

        var defaultText: String
        var time: Double
        switch type {
        case .none:
            defaultText = ""
            time = 0
        case .success:
            defaultText = "成功"
            time = indicatorTime
        case .fail:
            defaultText = "失败"
            time = indicatorTime
        }
            
        certainToast.setText(text: text ?? defaultText)
        
        if let certainDelay = delay {
            DispatchQueue.main.asyncAfter(deadline: .now() + certainDelay + showTime + time) {
                certainToast.animateHide(completion: completion)
            }
        }
    }
    
    init(frame: CGRect, toastType: ToastType, resultType: ResultType? = nil) {
        super.init(frame: frame)
        self.toastType = toastType
        setBackgroundView()
        setContentView(toastType: toastType, resultType: resultType)
        
    }
    
    /// 设置背景遮罩
    func setBackgroundView() {
        backgroundView = UIView(frame: frame)
        backgroundView?.backgroundColor = TCToast.maskColor
        backgroundView?.isUserInteractionEnabled = TCToast.isUserInteractionEnabled
        addSubview(backgroundView!)
        
        let tap = UITapGestureRecognizer(target: self, action: #selector(backgroundViewClicked))
        backgroundView?.addGestureRecognizer(tap)
    }
    
    /// 设置加载Toast内容视图
    func setContentView(toastType: ToastType, resultType: ResultType? = nil) {
        switch toastType {
        case .loading:
            contentView = ToastLoadingView()
        case .result:
            contentView = ToastResultView(type: resultType!)
        }
        contentView?.isUserInteractionEnabled = false
        contentView?.translatesAutoresizingMaskIntoConstraints = false
        addSubview(contentView!)
        
        let leftConstraint = NSLayoutConstraint(item: contentView!, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1, constant: 40)
        let rightConstraint = NSLayoutConstraint(item: contentView!, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1, constant: -40)
        let centerYConstraint = NSLayoutConstraint(item: contentView!, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0)
        
        addConstraint(leftConstraint)
        addConstraint(rightConstraint)
        addConstraint(centerYConstraint)
    }
    
    /// 获取控制器上的显示中的Toast
    static func getToast(in view: UIView) -> TCToast? {
        var toast: TCToast?
        for (_, view) in view.subviews.enumerated().reversed() {
            if view is TCToast {
                toast = view as? TCToast
                break
            }
        }
        return toast
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    /// 背景遮罩点击事件
    @objc private func backgroundViewClicked() {}
    
    /// 动态展示Toast
    func animateShow() {
        backgroundView?.alpha = 0
        contentView?.transform = CGAffineTransform(scaleX: scaleRatio, y: scaleRatio)
        contentView?.alpha = 0
        UIView.animate(withDuration: TCToast.showTime) { [self] in
            backgroundView?.alpha = 1
            contentView?.transform = CGAffineTransform.identity
            contentView?.alpha = 1
        } completion: { (_) in
            if self.contentView is ToastResultView {
                let view = self.contentView as? ToastResultView
                view?.startAnimation()
            }
        }
    }
    
    /// 动态消失Toast
    func animateHide(completion: (() -> Void)? = nil) {
        
        UIView.animate(withDuration: TCToast.dismissTime) { [self] in
            backgroundView?.alpha = 0
            contentView?.transform = CGAffineTransform(scaleX: scaleRatio, y: scaleRatio)
            contentView?.alpha = 0
        } completion: { _ in
            self.removeFromSuperview()
            if let certainCompletion = completion {
                certainCompletion()
            }
        }
    }
    
    /// 设置Toast显示文本
    func setText(text: String) {
        if contentView is ToastLoadingView {
            let view = contentView as? ToastLoadingView
            view?.textLabel?.text = text
        } else if contentView is ToastResultView {
            let view = contentView as? ToastResultView
            view?.textLabel?.text = text
        }
        self.layoutIfNeeded()
    }
}
